//Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using Eas.WebCrawler.Interfaces;

namespace Eas.WebCrawler.PlugIns.TemporaryStorage {

    /// <summary>A base class for <see cref="TemporaryStorageFactory"/>s that can use one of two different factories internally depending on the details of the web request.</summary>
    /// <remarks>Unlike other plugins in the webcrawler, this one had less need for extensibility, so we do not use a delegate here to determine which nested factory to use, instead we use an abstract method to be implemented in derived classes.</remarks>
    public abstract class ConditionalStorageFactory : Eas.WebCrawler.Interfaces.TemporaryStorageFactory{

        /// <summary>Context stored during <see cref="Initialize"/> and available for derived classes.</summary>
        /// <remarks>Backing field for the WebCrawlerContext property.</remarks>
        /// <seealso cref="WebCrawlerContext"/>
        private Eas.WebCrawler.Interfaces.WebCrawlerContext _WebCrawlerContext;

        /// <summary>Context stored during <see cref="Initialize"/> and available for derived classes.</summary>
        public Eas.WebCrawler.Interfaces.WebCrawlerContext WebCrawlerContext {
            get { return _WebCrawlerContext; }
            set { _WebCrawlerContext = value; }
        }

        private Eas.WebCrawler.Interfaces.TemporaryStorageFactory _TrueFactory;
        private Eas.WebCrawler.Interfaces.TemporaryStorageFactory _FalseFactory;

        /// <summary>Constructs a <see cref="ConditionalStorageFactory"/> from two different </summary>
        /// <param name="trueFactory">The factory to use if the <see cref="ConditionalCheck"/> returns <code>true</code>.</param>
        /// <param name="falseFactory">The factory to use if the <see cref="ConditionalCheck"/> returns <code>false</code>.</param>
        protected ConditionalStorageFactory(Eas.WebCrawler.Interfaces.TemporaryStorageFactory trueFactory, Eas.WebCrawler.Interfaces.TemporaryStorageFactory falseFactory) {
            _TrueFactory = trueFactory;
            _FalseFactory = falseFactory;
        }

        /// <summary>Implemented by derived classes to determine which factory to use.</summary>
        /// <param name="processingState">The details of the current request.</param>
        /// <returns><code>true</code> to use the trueFactory in this request, otherwise <code>false</code> to use the falseFactory.</returns>
        protected abstract bool ConditionalCheck(ProcessingState processingState);

        #region TemporaryStorageFactory Members

        /// <summary>Creates a new instance of a <see cref="TemporaryStorage"/>.</summary>
        /// <param name="processingState">The <see cref="ProcessingState"/> for the current request.</param>
        /// <returns>A new instance of a <see cref="TemporaryStorage"/>.</returns>
        public Eas.WebCrawler.Interfaces.TemporaryStorage Create(ProcessingState processingState) {
            if (ConditionalCheck(processingState))
                return _TrueFactory.Create(processingState);
            else
                return _FalseFactory.Create(processingState);
        }

        #endregion

        #region WebCrawlerComponent Members

        /// <summary>Initializes this class</summary>
        /// <param name="context">The <see cref="WebCrawlerContext"/> which will contain data about this instance of the web crawler.</param>
        public void Initialize(Eas.WebCrawler.Interfaces.WebCrawlerContext context) {
            WebCrawlerContext = context;
        }

        #endregion
    }
}
